<HTML>
<HEAD>
  <!-- Created with AOLpress/2.0 -->
  <!-- AP: Created on: 10-Nov-2005 -->
  <!-- AP: Last modified: 18-Oct-2007 -->
  <TITLE>Plugins in FontForge</TITLE>
</HEAD>
<BODY>
<H1 ALIGN=Center>
  Plugins in FontForge
</H1>
<P>
FontForge supports a plugin mechanism for extending its functionality.
<P>
Plugins are shared libraries that can be loaded at runtime. When fontforge
starts up (actually, when it loads its preferences) it will automatically
load all files that look like shared libraries and that live in the two
directories:
<UL>
  <LI>
    <CODE>/usr/local/share/fontforge/plugins</CODE><BR>
    (more precisely: <CODE>$(PREFIX)/share/fontforge/plugins</CODE>)
  <LI>
    <CODE>~/.FontForge/plugins</CODE>
</UL>
<P>
Most of what I once expected to do with plugins I now do with
<A HREF="python.html#python-init-scripts">python scripts</A>.
<H2>
  Installing a one of my example plugins
</H2>
<P>
Currently none of my pre-built packages contain any plugins. If you want
to play with them you must <A HREF="source-build.html">grab a source
distribution</A>, build it, and install it. Having done that type the following:
<BLOCKQUOTE>
  <PRE>$ cd plugins
$ make install
</PRE>
</BLOCKQUOTE>
<H2>
  Creating your own plugin
</H2>
<P>
FontForge currently supports two types of plugins:
<UL>
  <LI>
    plugins which add a 2byte encoding
  <LI>
    plugins which add a scripting command to the native scripting interface.
</UL>
<P>
(Actually I suppose there is a third type. When it loads a plugin FF calls
an initialization routine. I suppose the plugin could just start running
and doing things without ever returning to fontforge).
<P>
I once expected to add
<UL>
  <LI>
    plugins which add new menu items
</UL>
<P>
(but I did that in python instead).
<P>
When FontForge loads a plugin it calls a routine <CODE>int
FontForgeInit(void)</CODE>. This routine is responsible for registering the
plugin with FontForge, and then returning to allow FontForge to continue.
FontForge provides two registration routines:
<DL>
  <DT>
    <CODE>AddEncoding(char *name,int (*enc_to_uni)(int), int
    (*uni_to_enc)(int))</CODE>
  <DD>
    This registers a new encoding with the given name. You must supply two functions,
    one which converts from the encoding to unicode, and the other which converts
    from unicode to the encoding. <FONT COLOR="Red"><STRONG><BIG>NOTE:
    </BIG></STRONG></FONT>FontForge has a slightly unconventional definition
    of an encoding. It is not interested in byte streams, but in numbers. So
    if you have an 8/16 encoding (like EUC or SJIS) then the encoding of a character
    will be a number between 0 and 65535. A single byte will be a number &lt;256,
    while a double byte character will be a number like 0xa1a1.
    <P>
    This will return 0 if it failed (if you tried to replace a built in encoding
    for example), 1 if it added the encoding, 2 if it replaced a previous plugin
    with that name.
  <DT>
    <CODE>AddScriptingCommand(char *name, void (*UserScriptFunc)(Context *),
    int needs_font)</CODE>
  <DD>
    This will add a new scripting command with the given name. If that name is
    called then UserScriptFunc will be invoked with a Context (which contains
    information like the arguments passed, the current font, and into which you
    set the return value (if any) of your function). The final argument indicates
    whether your command needs a font to be loaded or not. (the command Open()
    does not need a font loaded. The command Close() does).
    <P>
    This will return 0 if it failed (if you tried to replace a built in scripting
    command for example), 1 if it added the command, 2 if it replaced a previous
    plugin with that name.
</DL>
<P>
You may register more than one thing in from <CODE>FontForgeInit</CODE>.
For example, many encodings have an EUC form and an ISO-2022 form and it
makes sense for one plugin to handle both.
<P>
<CODE>FontForgeInit</CODE> should return 1 if it succeeds, and 0 if it fails.
If it fails FontForge will dlclose() the library.
<P>
When you write your plugin you should include "plugins.h" from the fontforge
directory.
<P>
Look in the plugins subdirectory for an example on how to create, build &amp;
install a plugin.
</BODY></HTML>
